﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ruction.Mapping
{
	public delegate void NotifyProgressEventHandler(string message, bool append);

	/// <summary>Represents a game map.</summary>
	public class Map
	{
		private short Block;
		private short BlockTry;
		private string[] CName;
		private int Country;
		private int[] CountryClr;
		private bool CountryDone;
		private short CountrySize;
		private int Direction;
		private int[,] DisplaySpot = new int[1, 1];
		private bool FilledIn;
		private short[,] FlashArray = new short[1, 1];
		private bool FoundLand;
		private short FudgeCounter;
		public int LakeCode;
		private int LastDirection;
		private int[,] Map_Renamed = new int[115, 81];
		private string MapFileName;
		private string MapTimeStamp;
		public short MaxCountrySize;
		public short MinLakeSize;
		private int[,] Neighbor = new int[1, 1];
		private short NumCountries;
		private int OneAway;
		private short[] Owners;
		private float[,] Seed = new float[115, 81];
		private short[] Special;
		private int TempNum;
		private int[,] Tent = new int[3, 256];
		private short TentNum;
		private int[] TentOrder = new int[256];
		private int[] Troops;
		private int TryNumber;
		private short u;
		private string[] WName;
		private short XDimension;
		private short YDimension;
		private static int _rndSeed = DateTime.Now.Millisecond;

		public static float Rnd(float Number)
		{
			int rndSeed = _rndSeed;
			if (Number != 0.0)
			{
				if (Number < 0.0)
				{
					long num3 = BitConverter.ToInt32(BitConverter.GetBytes(Number), 0);
					num3 &= (long)4294967295L;
					rndSeed = (int)((num3 + (num3 >> 24)) & 16777215L);
				}
				rndSeed = (int)(((rndSeed * 1140671485L) + 12820163L) & 16777215L);
			}
			_rndSeed = rndSeed;
			return (((float)rndSeed) / 1.677722E+07f);
		}

		public static double Int(double Number)
		{
			return Math.Floor(Number);
		}

		public static float Int(float Number)
		{
			return (float)Math.Floor((double)Number);
		}

		private bool AddNeighbor(int ToCountry, int NewNeighbor)
		{
			bool AddNeighbor = true;
			if (ToCountry < 999)
			{
				int VB_CG_t_i4_S0;
				if (ToCountry == NewNeighbor)
				{
					return AddNeighbor;
				}
				short LastOne = -1;
				int k = 0;
				do
				{
					if (this.Neighbor[ToCountry, k] == NewNeighbor)
					{
						return AddNeighbor;
					}
					if ((LastOne == -1) && (this.Neighbor[ToCountry, k] == 0))
					{
						LastOne = (short)k;
					}
					k++;
					VB_CG_t_i4_S0 = 20;
				}
				while (k <= VB_CG_t_i4_S0 - 1);
				if (LastOne == -1)
				{
					return false;
				}
				this.Neighbor[ToCountry, LastOne] = NewNeighbor;
			}
			return AddNeighbor;
		}

		private void BuildSeedMatrix()
		{
			int i;
			bool[] marker = new bool[this.NumCountries + 1];
			int VB_t_i4_L0 = this.NumCountries;
			for (i = 0; i <= VB_t_i4_L0 - 1; i++)
			{
				marker[i] = false;
			}
			int VB_t_i4_L1 = this.XDimension;
			for (i = 0; i <= VB_t_i4_L1 - 1; i++)
			{
				int VB_t_i4_L2 = this.YDimension;
				for (int j = 0; j <= VB_t_i4_L2 - 1; j++)
				{
					if ((this.Map_Renamed[i, j] > 0) && (this.Map_Renamed[i, j] < 999))
					{
						if (marker[this.Map_Renamed[i, j]] && this.IsOnCoastLine(i, j))
						{
							this.Seed[i, j] = 0f;
							marker[this.Map_Renamed[i, j]] = true;
						}
						else
						{
							this.Seed[i, j] = Rnd(1f);
						}
					}
				}
			}
		}

		private bool ClearDirection(object Xcheck, object Ycheck)
		{
			bool ClearDirection = true;
			if ((this.Map_Renamed[Convert.ToInt32(Xcheck), Convert.ToInt32(Ycheck)] > 0) && (this.Map_Renamed[Convert.ToInt32(Xcheck), Convert.ToInt32(Ycheck)] < 999))
			{
				ClearDirection = false;
			}

			if (ClearDirection)
			{
				int VB_t_i4_L0 = this.TentNum;
				for (int i = 0; i <= VB_t_i4_L0 - 1; i++)
				{
					if (this.Tent[0, i].Equals(Xcheck) && this.Tent[1, i].Equals(Ycheck))
					{
						ClearDirection = false;
					}
				}
			}

			return ClearDirection;
		}

		private int CorrectColor(int Cntry)
		{
			if (this.FlashArray[Cntry, 0] == 0)
			{
				return this.CountryClr[Cntry];
			}
			return 12;
		}

		public void CreateMap(short CountryCount, short MaximumCountrySize, short MinimumLakeSize, double LandPct, double PropPct, double ShapePct, double CoastPctKeep, double IslePctKeep)
		{
			int i = 0;
			int j = 0;
			int x = 0;
			int y = 0;
			short LocalMax = 0;
			short LocalMin = 0;
			bool StillPossible = false;
			bool NewOrder = false;

			NumCountries = CountryCount;

			// We want some passed variables to stay public.
			MaxCountrySize = MaximumCountrySize;
			MinLakeSize = MinimumLakeSize;

			// Redimension our arrays to save some memory.
			Neighbor = new int[NumCountries, Constants.MAXIMUM_NEIGHBORS + 1];
			CountryClr = new int[NumCountries + 1];
			Owners = new short[NumCountries + 1];
			DisplaySpot = new int[NumCountries, 3 + 1];
			Troops = new int[NumCountries];
			Special = new short[NumCountries];
			CName = new string[NumCountries];
			FlashArray = new short[NumCountries, 4 + 1];

			for (; ((FindNeighbors() == true) == false); )
			{
				for (i = 0; (i < XDimension); i++)
				{
					for (j = 0; (j < YDimension); j++)
					{
						Map_Renamed[i, j] = Constants.TILEVAL_COASTLINE;
					}
				}

				Country = 0;
				while ((Country < NumCountries))
				{
					// Main Country Loop.
					Country = (Country + 1);

					StillKicking(); // Update our commentary line.

					FudgeCounter = 0;
					CountryDone = false;
					for (; (CountryDone == true); )
					{
						StillPossible = false;
						for (i = 0; (i < XDimension); i++)
						{
							for (j = 0; (j < YDimension); j++)
							{
								if (((Map_Renamed[i, j] == 0) || (Map_Renamed[i, j] == Constants.TILEVAL_COASTLINE)))
								{
									StillPossible = true;
									break;
								}
							}
						}

						StillKicking();

						if (StillPossible)
						{
							// Find the starting position of the next country.
							Constants.Done = false;
							for (; (Constants.Done == true); )
							{
								x = (int)(Int((Rnd(1) * XDimension)) + 1);
								y = (int)(Int((Rnd(1) * YDimension)) + 1);

								// Take care of the None or Lots of Islands options.
								if (((Constants.CFGIslands == 1) && (Map_Renamed[x, y] == Constants.TILEVAL_COASTLINE)))
								{
									Constants.Done = true;
								}

								if (((Constants.CFGIslands == 3) && ((Map_Renamed[x, y] == 0) || (Map_Renamed[x, y] == Constants.TILEVAL_COASTLINE))))
								{
									Constants.Done = true;
								}

								// The 'Some Islands' option is more complex.
								// If we found coastline, there's a large chance of keeping it.
								// If we found empty, there's a small chance of keeping it.
								if ((Constants.CFGIslands == 2))
								{
									if ((((Map_Renamed[x, y] == Constants.TILEVAL_COASTLINE) && (Rnd(1) < CoastPctKeep)) || ((Map_Renamed[x, y] == 0) && (Rnd(1) < IslePctKeep))))
									{
										Constants.Done = true;
									}
								}
							}
							// Place loop.
						}
						else
						{
							// Couldn't find a place for it, so we're done.
							EndItAll();
						}

						if (StillPossible)
						{
							// Clear out the last country by clearing out the tentative array.
							for (i = 0; (i < 2); i++)
							{
								for (j = 0; (j < (Constants.MAX_COUNTRY_SIZE * (1 + Constants.MAX_PROP_PCT))); j++)
								{
									Tent[i, j] = 0;
								}
							}

							// This is our first tentative block.
							Tent[0, 0] = x;
							Tent[1, 0] = y;
							TentNum = 1;

							// Get a random size for this country.
							if ((Constants.CFGCountrySize != 6))
							{
								if ((Rnd(1) < 0.5))
								{
									// Subtract a random amount within the proportional limit.
									CountrySize = (short)(MaxCountrySize - Int((Rnd(1) * (MaxCountrySize * PropPct))));
								}
								else
								{
									// Add a random amount within the proportional limit.  This will keep
									// all countries equal to MaxCountrySize on average.
									// (So it's not really a MAX then, is it?)
									CountrySize = (short)(MaxCountrySize + Int((Rnd(1) * (MaxCountrySize * PropPct))));
								}
							}
							else
							{
								// Hodge-Podge:  Pick anything between min and max.
								LocalMax = (short)(Constants.MAX_COUNTRY_SIZE * (1 + PropPct));
								LocalMin = (short)(Constants.MIN_COUNTRY_SIZE * (1 - PropPct));
								CountrySize = (short)(Int((Rnd(1) * (LocalMax - LocalMin))) + LocalMin);
							}

							NewOrder = true;
							for (; (TentNum == CountrySize); )
							{
								if ((NewOrder == true))
								{
									// Set up our array of integers.  There are TentNum integers to mix up.
									// This is the order that we check elements in the Tent array.
									for (i = 1; (i < TentNum); i++)
									{
										TentOrder[i] = i;
									}

									// Now randomize them a bit.  Don't move the last block.
									if ((TentNum > 4))
									{
										for (i = 0; (i <= (TentNum * 2)); i++)
										{
											for (; ((x != y) == false); )
											{
												x = (int)(Int((Rnd(1) * (TentNum - 1))) + 1);
												y = (int)(Int((Rnd(1) * (TentNum - 1))) + 1);
											}

											Block = (short)TentOrder[x];
											TentOrder[x] = TentOrder[y];
											TentOrder[y] = Block;
										}
									}

									// When BlockTry reaches TentNum, we've tried to bud off of every
									// square in this country.
									BlockTry = 0;

									// Regular or Irregular?
									// Block is which element in the Tent array we're trying to 'bud' off of.
									if ((Rnd(1) < ShapePct))
									{
										// Start at the first random block.
										Block = 1;
									}
									else
									{
										// Start at the last block we used.  Makes it more irregular.
										Block = TentNum;
									}
								}

								// NewOrder = true
								// Get the coordinates of a block in this country.
								x = Tent[0, TentOrder[Block]];
								y = Tent[1, TentOrder[Block]];

								// Pick a random direction for a contiguous block.
								NewDirection();
								Constants.Done = false;
								for (; ((TryNumber == 5) || (Constants.Done == true)); )
								{
									switch (Direction)
									{
										case Constants.UP:
											OneAway = (y - 1);
											if ((OneAway > 0))
											{
												// Check and see what's up.
												if ((ClearDirection(x, OneAway) == true))
												{
													// Map is clear in that direction.
													y = (y - 1);
													WriteToTent(x, y);
													Constants.Done = true;
												}
												else
												{
													// Blocked.  Try new direction.
													NextDirection();
												}
											}
											else
											{
												// We went off the top.  Try new direction.
												NextDirection();
											}
											break;
										case Constants.DOWN:
											OneAway = (y + 1);
											if ((OneAway <= YDimension))
											{
												// Check and see what's down.
												if ((ClearDirection(x, OneAway) == true))
												{
													// Map is clear in that direction.
													y = (y + 1);
													WriteToTent(x, y);
													Constants.Done = true;
												}
												else
												{
													// Blocked.  Try new direction.
													NextDirection();
												}
											}
											else
											{
												// We went off the bottom.  Try new direction.
												NextDirection();
											}
											break;
										case Constants.LEFTY:
											OneAway = (x - 1);
											if ((OneAway > 0))
											{
												// Check and see what's up.
												if ((ClearDirection(OneAway, y) == true))
												{
													// Map is clear in that direction.
													x = (x - 1);
													WriteToTent(x, y);
													Constants.Done = true;
												}
												else
												{
													// Blocked.  Try new direction.
													NextDirection();
												}
											}
											else
											{
												// We went off the left.  Try new direction.
												NextDirection();
											}
											break;
										case Constants.RIGHTY:
											OneAway = (x + 1);
											if ((OneAway <= XDimension))
											{
												// Check and see what's up.
												if ((ClearDirection(OneAway, y) == true))
												{
													// Map is clear in that direction.
													x = (x + 1);
													WriteToTent(x, y);
													Constants.Done = true;
												}
												else
												{
													// Blocked.  Try new direction.
													NextDirection();
												}
											}
											else
											{
												// We went off the right.  Try new direction.
												NextDirection();
											}
											break;
									}
								}

								// Each dir.
								if ((TryNumber == 5))
								{
									// This block is boxed in.  Try the next block in the country.
									NewOrder = false;
									Block++;
									if ((Block > TentNum))
									{
										Block = 1;
									}

									// Have we tried all blocks?
									BlockTry++;

									if ((BlockTry > TentNum))
									{
										// This Country cannot fit.  Need new starting location.
										// Remove this small area from further consideration -- probably a lake.
										for (i = 1; (i <= TentNum); i++)
										{
											// This space won't get picked next time.
											Map_Renamed[Tent[0, i], Tent[1, i]] = Constants.UNUSABLE_GRID;
										}

										TentNum = CountrySize;

										// Fudging out of loop.
										FudgeCounter++;
										StillPossible = false;
										if ((FudgeCounter > Constants.MAX_COUNTRY_TRIES))
										{
											// Screw it ... taking too long.  We're done.
											EndItAll();
										}
									}
								}
								else
								{
									NewOrder = true;
								}
							}

							// Block Search Loop.
							// Yay!  Our country is sitting in the Tent array.
							// Let's copy it over to the Map.
							// If we blew it last time, then we don't need to do anything here.
							if (StillPossible)
							{
								for (i = 0; (i <= CountrySize); i++)
								{
									Map_Renamed[Tent[0, i], Tent[1, i]] = Country;
								}
								// Let's outline all countries on the map with coastline.
								// Because if there are no islands, we must build on coastline next time.
								OutlineCoastline();
							}
							// StillPossible.
						}
						// StillPossible.
					}
					// This Country Loop.
				}
				// Main country loop.

				// Give us our final coastline.
				OutlineCoastline();

				// Fill in lakes according to lakesize parameter.
				FillLakes();

				// Populate the Neighbors array.
			}

			FindSpots();

			// Initialize the seed matrix.
			BuildSeedMatrix();

			// Clear out the troops, special, and flash arrays.  Name each country too.
			for (i = 0; (i < NumCountries); i++)
			{
				Troops[i] = 0;
				Special[i] = 0;
				for (j = 0; (j <= 4); j++)
				{
					FlashArray[i, j] = 0;
				}
				if (((Neighbor[i, 1] == 0)
							&& (Neighbor[i, 0] > Constants.TILEVAL_COASTLINE)))
				{
					// We have an island!  Let's give it an island name.
					CName[i] = NameGenerator.GenerateName(2, 6, false);
					TempNum = (int)(Int((Rnd(1) * 3)) + 23);

					if ((TempNum == 25))
					{
						CName[i] = (NameGenerator.NameSpice[TempNum] + (" " + CName[i]));
					}
					else
					{
						CName[i] = (CName[i] + (" " + NameGenerator.NameSpice[TempNum]));
					}
				}
				else
				{
					CName[i] = NameGenerator.GenerateName(2, 6, true);
				}
			}

			// Now let's name each body of water.
			if ((LakeCode == 1001))
			{
				// There were no bodies of water in this map.
				return;
			}

			// Let's set up the array.
			WName = new string[(LakeCode - 1000)]; // This blows up....why?

			for (i = (LakeCode - 1000); (i <= 1); i = (i + -1))
			{
				// Search the borders of the map for this lakecode.
				// Check the top and bottom borders.
				Constants.Done = false;
				for (j = 0; (j <= XDimension); j++)
				{
					if (((Map_Renamed[j, 0] == (i + 1000)) || (Map_Renamed[j, YDimension] == (i + 1000))))
					{
						// Yup, it's on the border.
						Constants.Done = true;
						break;
					}
				}

				// Check the left and right borders.
				for (j = 0; (j <= YDimension); j++)
				{
					if (((Map_Renamed[0, j] == (i + 1000)) || (Map_Renamed[XDimension, j] == (i + 1000))))
					{
						// Yup, it's on the border.
						Constants.Done = true;
						break;
					}
				}

				if ((Constants.Done == false))
				{
					// We haven't found it on the edge, so it must be a LAKE.
					switch ((int)(Int((Rnd(1) * 11)) + 1))
					{
						case 1:
						case 2:
						case 3:
							WName[i] = (NameGenerator.GenerateName(2, 6, false) + " Lake");
							break;
						case 4:
						case 5:
						case 6:
							WName[i] = ("Lake " + NameGenerator.GenerateName(2, 6, false));
							break;
						case 7:
							WName[i] = (NameGenerator.GenerateName(2, 6, false) + " Vista");
							break;
						case 8:
						case 9:
							WName[i] = (NameGenerator.GenerateName(2, 6, false) + " Sea");
							break;
						case 10:
						case 11:
							WName[i] = ("The Sea of " + NameGenerator.GenerateName(2, 6, false));
							break;
					}
				}
				else
				{
					// We found it on the edge of the map, so this is an OCEAN.
					switch ((int)(Int((Rnd(1) * 7)) + 1))
					{
						case 1:
							WName[i] = (NameGenerator.GenerateName(2, 6, false) + " Ocean");
							break;
						case 2:
						case 3:
							WName[i] = (NameGenerator.GenerateName(2, 6, false) + " Harbor");
							break;
						case 4:
						case 5:
							WName[i] = (NameGenerator.GenerateName(2, 6, false) + " Bay");
							break;
						case 6:
						case 7:
							WName[i] = ("The Bay of " + NameGenerator.GenerateName(2, 6, false));
							break;
					}
				}
			}

			// Finally, this is a fresh map so it hasn't been saved yet.
			MapFileName = null;
			MapTimeStamp = null;
		}

		private void EndItAll()
		{
			this.CountryDone = true;
			this.NumCountries = (short)(this.Country - 1);
			this.Neighbor = new int[this.NumCountries + 1, 21];
			this.CountryClr = new int[this.NumCountries + 1];
			this.Owners = new short[this.NumCountries + 1];
			this.DisplaySpot = new int[this.NumCountries + 1, 4];
			this.Troops = new int[this.NumCountries + 1];
			this.Special = new short[this.NumCountries + 1];
			this.CName = new string[this.NumCountries + 1];
			this.FlashArray = new short[this.NumCountries + 1, 5];
		}

		private object FillLakes()
		{
			object FillLakes = null;
			int j;
			int k;
			this.LakeCode = 1001;
			if (this.MinLakeSize == 0)
			{
				int VB_t_i4_L0 = this.XDimension;
				for (j = 0; j <= VB_t_i4_L0 - 1; j++)
				{
					int VB_t_i4_L1 = this.YDimension;
					k = 0;
					while (k <= VB_t_i4_L1 - 1)
					{
						if (this.Map_Renamed[j, k] == 999)
						{
							this.Map_Renamed[j, k] = this.LakeCode;
							this.LabelBodyOfWater(this.LakeCode);
							this.LakeCode++;
						}
						k++;
					}
				}
				return FillLakes;
			}
			int VB_t_i4_L2 = this.XDimension;
			for (j = 0; j <= VB_t_i4_L2 - 1; j++)
			{
				int VB_t_i4_L3 = this.YDimension;
				for (k = 0; k <= VB_t_i4_L3 - 1; k++)
				{
					this.FilledIn = false;
					if (this.Map_Renamed[j, k] == 999)
					{
						int VB_t_i4_L4 = this.MinLakeSize;
						int i = 0;
						while (i <= VB_t_i4_L4 - 1)
						{
							this.Tent[0, i] = 0;
							this.Tent[1, i] = 0;
							i++;
						}
						this.Tent[0, 0] = j;
						this.Tent[1, 0] = k;
						this.TentNum = 1;
						this.Country = 0;
						this.Block = 1;
						while (this.TentNum != this.MinLakeSize)
						{
							int x = this.Tent[0, this.Block];
							int y = this.Tent[1, this.Block];
							this.Direction = 1;
							Constants.Done = false;
							while (!((this.Direction == 5) || Constants.Done))
							{
								object VB_t_ref_S0;
								object VB_t_ref_S1;
								switch (this.Direction)
								{
									case 1:
										this.OneAway = y - 1;
										if (this.OneAway <= 0)
										{
											goto Label_026C;
										}
										VB_t_ref_S0 = x;
										VB_t_ref_S1 = this.OneAway;
										this.OneAway = Convert.ToInt32(VB_t_ref_S1);
										x = Convert.ToInt32(VB_t_ref_S0);
										if (!this.ClearDirection(VB_t_ref_S0, VB_t_ref_S1))
										{
											break;
										}
										y--;
										this.WriteToTent(x, y);
										Constants.Done = true;
										goto Label_04FC;

									case 2:
										this.OneAway = y + 1;
										if (this.OneAway > this.YDimension)
										{
											goto Label_0344;
										}
										VB_t_ref_S1 = x;
										VB_t_ref_S0 = this.OneAway;
										this.OneAway = Convert.ToInt32(VB_t_ref_S0);
										x = Convert.ToInt32(VB_t_ref_S1);
										if (!this.ClearDirection(VB_t_ref_S1, VB_t_ref_S0))
										{
											goto Label_02FB;
										}
										y++;
										this.WriteToTent(x, y);
										Constants.Done = true;
										goto Label_04FC;

									case 3:
										this.OneAway = x - 1;
										if (this.OneAway <= 0)
										{
											goto Label_0414;
										}
										VB_t_ref_S1 = this.OneAway;
										VB_t_ref_S0 = y;
										y = Convert.ToInt32(VB_t_ref_S0);
										this.OneAway = Convert.ToInt32(VB_t_ref_S1);
										if (!this.ClearDirection(VB_t_ref_S1, VB_t_ref_S0))
										{
											goto Label_03CB;
										}
										x--;
										this.WriteToTent(x, y);
										Constants.Done = true;
										goto Label_04FC;

									case 4:
										this.OneAway = x + 1;
										if (this.OneAway > this.XDimension)
										{
											goto Label_04EC;
										}
										VB_t_ref_S1 = this.OneAway;
										VB_t_ref_S0 = y;
										y = Convert.ToInt32(VB_t_ref_S0);
										this.OneAway = Convert.ToInt32(VB_t_ref_S1);
										if (!this.ClearDirection(VB_t_ref_S1, VB_t_ref_S0))
										{
											goto Label_04A3;
										}
										x++;
										this.WriteToTent(x, y);
										Constants.Done = true;
										goto Label_04FC;

									default:
										goto Label_04FC;
								}
								VB_t_ref_S1 = x;
								VB_t_ref_S0 = this.OneAway;
								this.GetAdjacentColor(VB_t_ref_S1, VB_t_ref_S0);
								this.OneAway = Convert.ToInt32(VB_t_ref_S0);
								x = Convert.ToInt32(VB_t_ref_S1);
								this.Direction++;
								goto Label_04FC;
							Label_026C:
								this.Direction++;
								goto Label_04FC;
							Label_02FB:
								VB_t_ref_S1 = x;
								VB_t_ref_S0 = this.OneAway;
								this.GetAdjacentColor(VB_t_ref_S1, VB_t_ref_S0);
								this.OneAway = Convert.ToInt32(VB_t_ref_S0);
								x = Convert.ToInt32(VB_t_ref_S1);
								this.Direction++;
								goto Label_04FC;
							Label_0344:
								this.Direction++;
								goto Label_04FC;
							Label_03CB:
								VB_t_ref_S1 = this.OneAway;
								VB_t_ref_S0 = y;
								this.GetAdjacentColor(VB_t_ref_S1, VB_t_ref_S0);
								y = Convert.ToInt32(VB_t_ref_S0);
								this.OneAway = Convert.ToInt32(VB_t_ref_S1);
								this.Direction++;
								goto Label_04FC;
							Label_0414:
								this.Direction++;
								goto Label_04FC;
							Label_04A3:
								VB_t_ref_S1 = this.OneAway;
								VB_t_ref_S0 = y;
								this.GetAdjacentColor(VB_t_ref_S1, VB_t_ref_S0);
								y = Convert.ToInt32(VB_t_ref_S0);
								this.OneAway = Convert.ToInt32(VB_t_ref_S1);
								this.Direction++;
								goto Label_04FC;
							Label_04EC:
								this.Direction++;
							Label_04FC: ;
							}
							if (this.Direction == 5)
							{
								this.Block = (short)(this.Block + 1);
								if (this.Block > this.TentNum)
								{
									int VB_t_i4_L6 = this.TentNum;
									i = 0;
									while (i <= VB_t_i4_L6 - 1)
									{
										this.Map_Renamed[this.Tent[0, i], this.Tent[1, i]] = this.Country;
										i++;
									}
									this.TentNum = this.MinLakeSize;
									this.FilledIn = true;
								}
							}
							if (Constants.Done)
							{
								this.Block = 1;
							}
						}
						if (!this.FilledIn)
						{
							int VB_t_i4_L7 = this.TentNum;
							for (i = 0; i <= VB_t_i4_L7 - 1; i++)
							{
								this.Map_Renamed[this.Tent[0, i], this.Tent[1, i]] = this.LakeCode;
							}
							this.LabelBodyOfWater(this.LakeCode);
							this.LakeCode++;
						}
					}
				}
			}
			return FillLakes;
		}

		private bool FindNeighbors()
		{
			int i;
			int j;
			int VB_CG_t_i4_S0;
			int VB_t_i4_L0 = this.NumCountries;
			for (i = 0; i <= VB_t_i4_L0 - 1; i++)
			{
				j = 0;
				do
				{
					this.Neighbor[i, j] = 0;
					j++;
					VB_CG_t_i4_S0 = 20;
				}
				while (j <= VB_CG_t_i4_S0 - 1);
			}
			int VB_t_i4_L1 = this.XDimension;
			for (i = 0; i <= VB_t_i4_L1 - 1; i++)
			{
				this.StillKicking();
				int VB_t_i4_L2 = this.YDimension;
				j = 0;
				while (j <= VB_t_i4_L2 - 1)
				{
					bool FindNeighbors = false;
					int x = i;
					int y = j;
					if ((y - 1) > 0)
					{
						FindNeighbors = this.AddNeighbor(this.Map_Renamed[x, y], this.Map_Renamed[x, y - 1]);
					}
					if ((y + 1) <= this.YDimension)
					{
						FindNeighbors = this.AddNeighbor(this.Map_Renamed[x, y], this.Map_Renamed[x, y + 1]);
					}
					if ((x - 1) > 0)
					{
						FindNeighbors = this.AddNeighbor(this.Map_Renamed[x, y], this.Map_Renamed[x - 1, y]);
					}
					if ((x + 1) <= this.XDimension)
					{
						FindNeighbors = this.AddNeighbor(this.Map_Renamed[x, y], this.Map_Renamed[x + 1, y]);
					}
					if (!FindNeighbors)
					{
						return FindNeighbors;
					}
					j++;
				}
			}
			int VB_t_i4_L3 = this.NumCountries;
			for (i = 0; i <= VB_t_i4_L3 - 1; i++)
			{
				Constants.Done = false;
				while (!Constants.Done)
				{
					Constants.Done = true;
					j = 19;
					do
					{
						if ((this.Neighbor[i, j + 1] < this.Neighbor[i, j]) && (this.Neighbor[i, j + 1] != 0))
						{
							int k = this.Neighbor[i, j + 1];
							this.Neighbor[i, j + 1] = this.Neighbor[i, j];
							this.Neighbor[i, j] = k;
							Constants.Done = false;
						}
						j += -1;
						VB_CG_t_i4_S0 = 1;
					}
					while (j >= VB_CG_t_i4_S0);
				}
			}
			return true;
		}

		private void FindSpots()
		{
			int i;
			int VB_t_i4_L0 = this.NumCountries;
			for (i = 0; i <= VB_t_i4_L0 - 1; i++)
			{
				this.DisplaySpot[i, 0] = 0;
				this.DisplaySpot[i, 1] = 0;
				this.DisplaySpot[i, 2] = 0;
			}
			int VB_t_i4_L1 = this.Xsize;
			for (i = 0; i <= VB_t_i4_L1 - 1; i++)
			{
				this.StillKicking();
				int VB_t_i4_L2 = this.Ysize;
				for (int j = 0; j <= VB_t_i4_L2 - 1; j++)
				{
					int CurrentCountry = this.Map_Renamed[i, j];
					if ((CurrentCountry > 0) && (CurrentCountry < 999))
					{
						int VB_CG_t_i4_S0;
						short LandCount = 0;
						int k = -2;
						do
						{
							int l = -2;
							do
							{
								int x = i + k;
								int y = j + l;
								if (((((x >= 0) && (x <= this.Xsize)) && (y >= 0)) && (y <= this.Ysize)) && (this.Map_Renamed[x, y] == CurrentCountry))
								{
									if ((l == 0) && ((k == -1) || (k == 1)))
									{
										LandCount = (short)(LandCount + 9);
									}
									else if (((l == -1) || (l == 1)) && ((k > -2) && (k < 2)))
									{
										LandCount = (short)(LandCount + 3);
									}
									else
									{
										LandCount = (short)(LandCount + 1);
									}
								}
								l++;
								VB_CG_t_i4_S0 = 2;
							}
							while (l <= VB_CG_t_i4_S0 - 1);
							k++;
							VB_CG_t_i4_S0 = 2;
						}
						while (k <= VB_CG_t_i4_S0 - 1);
						if (LandCount > this.DisplaySpot[CurrentCountry, 2])
						{
							this.DisplaySpot[CurrentCountry, 0] = i;
							this.DisplaySpot[CurrentCountry, 1] = j;
							this.DisplaySpot[CurrentCountry, 2] = LandCount;
						}
						else if ((LandCount == this.DisplaySpot[CurrentCountry, 2]) && (Rnd(1f) < 0.05))
						{
							this.DisplaySpot[CurrentCountry, 0] = i;
							this.DisplaySpot[CurrentCountry, 1] = j;
							this.DisplaySpot[CurrentCountry, 2] = LandCount;
						}
					}
				}
			}
		}

		private object GetAdjacentColor(object Xcheck, object Ycheck)
		{
			object GetAdjacentColor = null;
			if (((this.Map_Renamed[Convert.ToInt32(Xcheck), Convert.ToInt32(Ycheck)] != 0) && (this.Map_Renamed[Convert.ToInt32(Xcheck), Convert.ToInt32(Ycheck)] != 999)) && (this.Country == 0))
			{
				this.Country = this.Map_Renamed[Convert.ToInt32(Xcheck), Convert.ToInt32(Ycheck)];
			}
			return GetAdjacentColor;
		}

		private bool IsOnCoastLine(int ii, int jj)
		{
			return ((((((((this.LookRight(ii, jj) >= 999) || (this.LookLeft(ii, jj) >= 999)) || (this.LookUp(ii, jj) >= 999)) ||
				(this.LookDown(ii, jj) >= 999)) || (this.LookRight(ii, jj) == 0)) || (this.LookLeft(ii, jj) == 0)) ||
				(this.LookUp(ii, jj) == 0)) || (this.LookDown(ii, jj) == 0));
		}

		private void LabelBodyOfWater(int LakeCode)
		{
			this.StillKicking();
			Constants.Done = false;
			while (!Constants.Done)
			{
				Constants.Done = true;
				int VB_t_i4_L0 = this.XDimension;
				for (int ii = 0; ii <= VB_t_i4_L0 - 1; ii++)
				{
					int VB_t_i4_L1 = this.YDimension;
					for (int jj = 0; jj <= VB_t_i4_L1 - 1; jj++)
					{
						if (this.Map_Renamed[ii, jj] == LakeCode)
						{
							int xx = ii;
							int yy = jj;
							if ((yy - 1) > 0)
							{
								if ((this.Map_Renamed[xx, yy - 1] == 0) || (this.Map_Renamed[xx, yy - 1] == 999))
								{
									this.Map_Renamed[xx, yy - 1] = LakeCode;
									Constants.Done = false;
								}
								if (((xx - 1) > 0) && ((this.Map_Renamed[xx - 1, yy - 1] == 0) || (this.Map_Renamed[xx - 1, yy - 1] == 999)))
								{
									this.Map_Renamed[xx - 1, yy - 1] = LakeCode;
									Constants.Done = false;
								}
							}
							if ((yy + 1) <= this.YDimension)
							{
								if ((this.Map_Renamed[xx, yy + 1] == 0) || (this.Map_Renamed[xx, yy + 1] == 999))
								{
									this.Map_Renamed[xx, yy + 1] = LakeCode;
									Constants.Done = false;
								}
								if (((xx + 1) <= this.XDimension) && ((this.Map_Renamed[xx + 1, yy + 1] == 0) || (this.Map_Renamed[xx + 1, yy + 1] == 999)))
								{
									this.Map_Renamed[xx + 1, yy + 1] = LakeCode;
									Constants.Done = false;
								}
							}
							if ((xx - 1) > 0)
							{
								if ((this.Map_Renamed[xx - 1, yy] == 0) || (this.Map_Renamed[xx - 1, yy] == 999))
								{
									this.Map_Renamed[xx - 1, yy] = LakeCode;
									Constants.Done = false;
								}
								if (((yy + 1) <= this.YDimension) && ((this.Map_Renamed[xx - 1, yy + 1] == 0) || (this.Map_Renamed[xx - 1, yy + 1] == 999)))
								{
									this.Map_Renamed[xx - 1, yy + 1] = LakeCode;
									Constants.Done = false;
								}
							}
							if ((xx + 1) <= this.XDimension)
							{
								if ((this.Map_Renamed[xx + 1, yy] == 0) || (this.Map_Renamed[xx + 1, yy] == 999))
								{
									this.Map_Renamed[xx + 1, yy] = LakeCode;
									Constants.Done = false;
								}
								if (((yy - 1) > 0) && ((this.Map_Renamed[xx + 1, yy - 1] == 0) || (this.Map_Renamed[xx + 1, yy - 1] == 999)))
								{
									this.Map_Renamed[xx + 1, yy - 1] = LakeCode;
									Constants.Done = false;
								}
							}
						}
					}
				}
			}
		}

		private int LookDown(int ii, int jj)
		{
			int LookDown = -1;
			int xx = ii;
			int yy = jj + 1;
			if (yy < this.YDimension)
			{
				LookDown = this.Map_Renamed[xx, yy];
			}
			return LookDown;
		}

		private int LookDownRight(int ii, int jj)
		{
			int LookDownRight = -1;
			int xx = ii + 1;
			int yy = jj + 1;
			if ((yy < this.YDimension) && (xx < this.XDimension))
			{
				LookDownRight = this.Map_Renamed[xx, yy];
			}
			return LookDownRight;
		}

		private int LookLeft(int ii, int jj)
		{
			int LookLeft = -1;
			int xx = ii - 1;
			int yy = jj;
			if (xx >= 0)
			{
				LookLeft = this.Map_Renamed[xx, yy];
			}
			return LookLeft;
		}

		private int LookRight(int ii, int jj)
		{
			int LookRight = -1;
			int xx = ii + 1;
			int yy = jj;
			if (xx < this.XDimension)
			{
				LookRight = this.Map_Renamed[xx, yy];
			}
			return LookRight;
		}

		private int LookUp(int ii, int jj)
		{
			int LookUp = -1;
			int xx = ii;
			int yy = jj - 1;
			if (yy >= 0)
			{
				LookUp = this.Map_Renamed[xx, yy];
			}
			return LookUp;
		}

		private int LookUpLeft(int ii, int jj)
		{
			int LookUpLeft = -1;
			int xx = ii - 1;
			int yy = jj - 1;
			if ((yy >= 0) && (xx >= 0))
			{
				LookUpLeft = this.Map_Renamed[xx, yy];
			}
			return LookUpLeft;
		}

		private int LookUpRight(int ii, int jj)
		{
			int LookUpRight = -1;
			int xx = ii + 1;
			int yy = jj - 1;
			if ((yy >= 0) && (xx < this.XDimension))
			{
				LookUpRight = this.Map_Renamed[xx, yy];
			}
			return LookUpRight;
		}

		private object NewDirection()
		{
			object NewDirection = null;
			this.LastDirection = this.Direction;
			if ((this.LastDirection < 1) || (this.LastDirection > 4))
			{
				this.LastDirection = Convert.ToInt32(this.RandomDir());
			}
			this.Direction = Convert.ToInt32(this.RandomDir());
			this.TryNumber = 1;
			return NewDirection;
		}

		private object NextDirection()
		{
			object NextDirection = null;
			this.Direction++;
			if (this.Direction == 5)
			{
				this.Direction = 1;
			}
			this.TryNumber++;
			return NextDirection;
		}

		private void OutlineCoastline()
		{
			short VB_t_i2_L0 = this.XDimension;
			for (short i = 0; i <= VB_t_i2_L0 - 1; i = (short)(i + 1))
			{
				short VB_t_i2_L1 = this.YDimension;
				for (short j = 0; j <= VB_t_i2_L1 - 1; j = (short)(j + 1))
				{
					if (((this.Country == 1) && (this.Map_Renamed[i, j] == 999)) || (this.Map_Renamed[i, j] == -37))
					{
						this.Map_Renamed[i, j] = 0;
					}
					if ((this.Map_Renamed[i, j] == 0) || (this.Map_Renamed[i, j] > 999))
					{
						this.FoundLand = false;
						short x = i;
						short y = (short)(j - 1);
						if ((y >= 0) && ((this.Map_Renamed[x, y] > 0) && (this.Map_Renamed[x, y] < 999)))
						{
							this.FoundLand = true;
						}
						x = i;
						y = (short)(j + 1);
						if ((y < this.YDimension) && ((this.Map_Renamed[x, y] > 0) && (this.Map_Renamed[x, y] < 999)))
						{
							this.FoundLand = true;
						}
						x = (short)(i - 1);
						y = j;
						if ((x >= 0) && ((this.Map_Renamed[x, y] > 0) && (this.Map_Renamed[x, y] < 999)))
						{
							this.FoundLand = true;
						}
						x = (short)(i + 1);
						y = j;
						if ((x < this.XDimension) && ((this.Map_Renamed[x, y] > 0) && (this.Map_Renamed[x, y] < 999)))
						{
							this.FoundLand = true;
						}
						if (this.FoundLand)
						{
							this.Map_Renamed[i, j] = 999;
						}
						else
						{
							this.Map_Renamed[i, j] = 0;
						}
					}
				}
			}
		}

		private object RandomDir()
		{
			return (Int((float)(Rnd(1f) * 4f)) + 1f);
		}

		public void RedimensionStuff(int xxx, int yyy)
		{
			try
			{
				this.NumCountries = (short)xxx;
				this.LakeCode = yyy;
				this.Neighbor = new int[this.NumCountries + 1, 21];
				this.CountryClr = new int[this.NumCountries + 1];
				this.Owners = new short[this.NumCountries + 1];
				this.DisplaySpot = new int[this.NumCountries + 1, 4];
				this.Troops = new int[this.NumCountries + 1];
				this.Special = new short[this.NumCountries + 1];
				this.CName = new string[this.NumCountries + 1];
				this.WName = new string[(this.LakeCode - 1000) + 1];
				this.FlashArray = new short[this.NumCountries + 1, 5];
			}
			catch (Exception)
			{
			}
		}

		public void SetDimensions(short x, short y)
		{
			this.XDimension = x;
			this.YDimension = y;
		}

		private void StillKicking()
		{
		}

		public bool UpdateFlashing(int Cntry)
		{
			bool UpdateFlashing = false;
			if (this.FlashArray[Cntry, 1] > 0)
			{
				this.FlashArray[Cntry, 1] = (short)(this.FlashArray[Cntry, 1] - 1);
				if (this.FlashArray[Cntry, 1] != 0)
				{
					return UpdateFlashing;
				}
				this.FlashArray[Cntry, 0] = (short)(1 - this.FlashArray[Cntry, 0]);
				UpdateFlashing = true;
				this.FlashArray[Cntry, 3] = (short)(this.FlashArray[Cntry, 3] - 1);
				if (this.FlashArray[Cntry, 3] > 0)
				{
					this.FlashArray[Cntry, 1] = this.FlashArray[Cntry, 2];
				}
			}
			return UpdateFlashing;
		}

		private object WriteToTent(int x, int y)
		{
			object WriteToTent = null;
			this.TentNum = (short)(this.TentNum + 1);
			this.Tent[0, this.TentNum] = x;
			this.Tent[1, this.TentNum] = y;
			if (this.TentNum == this.CountrySize)
			{
				this.CountryDone = true;
			}
			return WriteToTent;
		}

		public string MapName
		{
			get
			{
				return this.MapFileName;
			}
			set
			{
				this.MapFileName = value;
			}
		}

		public string MapStamp
		{
			get
			{
				return this.MapTimeStamp;
			}
			set
			{
				this.MapTimeStamp = value;
			}
		}

		public short MaxNeighbors
		{
			get
			{
				return 20;
			}
		}

		public short NumberOfCountries
		{
			get
			{
				return this.NumCountries;
			}
		}

		public short Xsize
		{
			get
			{
				return this.XDimension;
			}
		}

		public short Ysize
		{
			get
			{
				return this.YDimension;
			}
		}
	}
}